package com.example.demo.api;

import com.example.demo.api.wechat.MessageUtil;
import com.example.demo.api.wechat.WXBizMsgCrypt;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Map;

/**
 * 企业微信回调 .
 * 这里配置的接口必须是外网可以访问
 * 可以使用花生壳映射一个备案过的域名或者下载一个 utools 使用里面的nat功能进行映射
 * @author c.w
 */
@Slf4j
@Controller
@RequestMapping("/api/qywechat")
public class QyContactApiController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     * get 请求  验签.
     *
     * @param msgSignature 加密
     * @param timestamp    时间戳
     * @param nonce        随机
     * @param echostr      .
     * @param response     .
     * @throws Exception .
     */
    @RequestMapping(value = "/callback",method = RequestMethod.GET)
    public void reveiceMsg(@RequestParam(name = "msg_signature") final String msgSignature,
                           @RequestParam(name = "timestamp") final String timestamp,
                           @RequestParam(name = "nonce") final String nonce,
                           @RequestParam(name = "echostr") final String echostr,
                           final HttpServletResponse response) throws Exception {
        //企业回调的url-----该url不做任何的业务逻辑，仅仅微信查看是否可以调通.
        QywechatCallback qywechatCallback = QywechatCallback.TEST;
        logger.info(" msg_signature {}, timestamp {}, nonce {} , echostr {}", msgSignature, timestamp, nonce, echostr);
        WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(qywechatCallback);
        // 随机字符串
        String sEchoStr = wxcpt.verifyURL(msgSignature, timestamp, nonce, echostr);
        PrintWriter out = response.getWriter();
        try {
            //必须要返回解密之后的明文
            if (StringUtils.isBlank(sEchoStr)) {
                logger.info("URL验证失败");
            } else {
                logger.info("验证成功!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        out.write(sEchoStr);
        out.flush();
    }

    /**
     * 企业微信客户联系回调.
     *
     * @param request       request
     * @param sMsgSignature 签名
     * @param sTimestamp    时间戳
     * @param sNonce        随机值
     * @return success
     */
    @ResponseBody
    @PostMapping(value = "/callback")
    public String acceptMessage(final HttpServletRequest request,
                              @RequestParam(name = "msg_signature") final String sMsgSignature,
                              @RequestParam(name = "timestamp") final String sTimestamp,
                              @RequestParam(name = "nonce") final String sNonce) {

        QywechatCallback qywechatCallback = QywechatCallback.TEST;

        try {
            InputStream inputStream = request.getInputStream();
            String sPostData = IOUtils.toString(inputStream, "UTF-8");
            QywechatUserBean qywechatUserBean = new QywechatUserBean();
            qywechatUserBean.setMsgSignature(sMsgSignature);
            qywechatUserBean.setNonce(sNonce);
            qywechatUserBean.setQywechatCallback(qywechatCallback);
            qywechatUserBean.setTimestamp(sTimestamp);
            qywechatUserBean.setSPostData(sPostData);
            //下面这些操作都可以异步  如果处理请求比较慢，企业微信会重复推送 这里需要去重保证执行唯一
            WXBizMsgCrypt msgCrypt = new WXBizMsgCrypt(qywechatUserBean.getQywechatCallback());
            //解密
            String sMsg = msgCrypt.decryptMsg(qywechatUserBean);
            //将post数据转换为map
            Map<String, String> dataMap = MessageUtil.parseXml(sMsg);
            //处理逻辑
            System.out.println(dataMap);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "success";
    }

}
